package RPC

import (
	pb "AttackTracer/RpcMessage/AttackTracer/RpcMessage"
	"AttackTracer/Tracker/config"
	"context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/keepalive"
	"log"
	"time"
)

var (
	kacp = keepalive.ClientParameters{
		Time:                10 * time.Second, // send pings every 10 seconds if there is no activity
		Timeout:             time.Second,      // wait 1 second for ping ack before considering the connection dead
		PermitWithoutStream: true,             // send pings even without active streams
	}
	rpcConfig config.Rpc
)

func ConnectAnalyzer(rpcConf config.Rpc, incidentChann chan Incident) {
	rpcConfig = rpcConf
	conn, err := grpc.Dial(rpcConfig.AnalyzerAddr,
		grpc.WithPerRPCCredentials(&loginCreds{AccessKey: rpcConf.AuthKey, Id: rpcConfig.Id}),
		grpc.WithInsecure(),
		grpc.WithKeepaliveParams(kacp))
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	c := pb.NewTrackerAnalyzerClient(conn)

	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
	defer cancel()
	// SayHello test
	r, err := c.SayHello(ctx, &pb.HelloRequest{Id: rpcConfig.Id})
	if err != nil {
		log.Fatalf("could not greet: %v", err)
	}
	log.Println("Response:", r.GetMessage())

	// Read incidents from other function modules
	for incident := range incidentChann {
		// convert incident to RpcRequest &
		// report incident to TracingEngine
		if err := reportIncident(incident, c, ctx); err != nil {
			log.Println(err)
		}
	}
}

// login credential definition
type loginCreds struct {
	AccessKey string
	Id        string
}

func (c *loginCreds) GetRequestMetadata(context.Context, ...string) (map[string]string, error) {
	return map[string]string{
		"AccessKey": c.AccessKey,
		"Id":        c.Id,
	}, nil
}
func (c *loginCreds) RequireTransportSecurity() bool {
	return false
}
